import tools from "../tools"

export default class KeyDetail extends Element {
    key = null

    constructor() {
        super()
        document.on("db-change", () => {
            this.key = null
        })
        document.on("key-change", (evt) => {
            this.key = evt.data.key
            this.getKeyInfo()
        })
    }

    /**
     * 重置初始化数据
     */
    resetInitData() {
        this.key = null
        this.info = []
    }

    /**
     * 刷新key列表
     */
    refreshKeyList() {
        this.post(new Event("refresh-key-list", {bubbles: true}))
        this.getKeyInfo()
    }

    /**
     * 获取key信息
     */
    getKeyInfo() {
        if (!this.key) {
            return
        }
        this.info = tools.getView().xcall("get_infos", this.key).split(",")
        if (this.info[0] === "") {
            this.resetInitData()
        }
        this.componentUpdate()
    }

    /**
     * 新增key
     */
    addKey() {
        setTimeout(() => {
            let [x, y] = tools.windowPosition()
            let [w, h] = tools.windowSize()
            let modal = tools.getView().modal({
                width: 320,
                height: 230,
                x: x + w / 2 - 320 / 2,
                y: y + h / 2 - 230 / 2,
                url: "/redis/maintain_key.html",
                parameters: {
                    title: "新增key",
                    view: tools.getView()
                }
            })
            if (modal === true) {
                this.refreshKeyList()
            }
        })
    }

    /**
     * 删除key
     */
    deleteKey() {
        if (!this.key) {
            return
        }
        tools.confirm("确定要删除吗？")
            .then(res => {
                if (res === true) {
                    let res = tools.getView().xcall("delete_key", this.key)
                    if (res) {
                        tools.alert("删除成功")
                            .then(() => {
                                this.resetInitData()
                                this.refreshKeyList()
                                this.componentUpdate()
                            })
                    } else {
                        tools.alert("删除失败")
                    }
                }
            })

    }

    /**
     * 重命名
     */
    renameKey() {
        if (!this.key) {
            return
        }
        setTimeout(() => {
            let [x, y] = tools.windowPosition()
            let [w, h] = tools.windowSize()
            let modal = tools.getView().modal({
                width: 320,
                height: 200,
                x: x + w / 2 - 320 / 2,
                y: y + h / 2 - 200 / 2,
                url: "/redis/rename_key.html",
                parameters: {
                    title: "重命名key",
                    view: tools.getView(),
                    key: this.key
                }
            })
            if (modal.key) {
                this.key = modal.key
                this.getKeyInfo()
                this.refreshKeyList()
            }
        })

    }

    ttlKey() {
        if (!this.key) {
            return
        }
        setTimeout(() => {
            let [x, y] = tools.windowPosition()
            let [w, h] = tools.windowSize()
            let modal = tools.getView().modal({
                width: 320,
                height: 240,
                x: x + w / 2 - 320 / 2,
                y: y + h / 2 - 240 / 2,
                url: "/redis/expire_key.html",
                parameters: {
                    title: "重设过期时间",
                    view: tools.getView(),
                    key: this.key
                }
            })
            if (modal === true) {
                this.getKeyInfo()
            }
        })
    }

    /**
     * 渲染string类型的数据
     */
    renderString() {
        let value = tools.getView().xcall("get_string_val", this.key)
        return <div class="key-result">
            <b><code>{this.key}</code>的查询结果：</b>
            <br/>
            <div class="string">
                <div class="copy" onClick={() => this.doCopy(value)}>复制</div>
                <div style="margin:3px 8px">{value}</div>
            </div>
        </div>
    }

    /**
     * 分页
     * @type {{current: number, total: number, size: number}}
     */
    page = {
        current: 1,
        size: 10,
        total: 0
    }

    /**
     * 执行复制功能
     * @param val
     */
    doCopy(val) {
        Clipboard.writeText(val)
    }

    /**
     * 导出数据
     */
    exportFile(data) {
        let file = tools.getView().selectFile({
            mode: "save",
            filter: "JSON文件|*.json",
            caption: `保存为`,
            path: `${this.key}.json`
        })
        if (file) {
            tools.sys.fs.open(file.slice(7), "wb+")
                .then(fd => {
                    return fd.write(data)
                })
                .then(() => {
                    tools.alert("保存成功！")
                })
                .catch(e => {
                    console.log("err", e)
                })
        }
    }

    /**
     * list类型渲染
     * @returns {JSX.Element}
     */
    renderList() {
        let res = tools.xcall("get_list_val", this.key, Number(this.page.current), Number(this.page.size))
        let list = []
        try {
            res = JSON.parse(res)
            list = JSON.parse(res.list)
        } catch (e) {
            res = {
                current: 1,
                size: 10,
                total: 0,
                list: "[]"
            }
        }

        this.page.current = res.current
        this.page.size = res.size
        this.page.total = res.total

        return <div class="list-info">
            <div class="list-info-title">
                <span><b>{this.key}</b>查询结果</span>
                <div class="list-info-title-action">
                    <div class="btn" onClick={() => {
                        setTimeout(() => {
                            let [x, y] = tools.windowPosition()
                            let [w, h] = tools.windowSize()
                            let modal = tools.getView().modal({
                                width: 320,
                                height: 240,
                                x: x + w / 2 - 320 / 2,
                                y: y + h / 2 - 240 / 2,
                                url: "/redis/append_list_exist_key_value.html",
                                parameters: {
                                    title: "插入新值",
                                    view: tools.getView(),
                                    key: this.key,
                                }
                            })
                            if (modal === true) {
                                this.componentUpdate()
                            }
                        })

                    }}>新增
                    </div>
                    <div class="btn" onClick={() => {
                        setTimeout(() => {
                            let [x, y] = tools.windowPosition()
                            let [w, h] = tools.windowSize()
                            let modal = tools.getView().modal({
                                width: 320,
                                height: 240,
                                x: x + w / 2 - 320 / 2,
                                y: y + h / 2 - 240 / 2,
                                url: "/redis/clip_list.html",
                                parameters: {
                                    title: "裁剪list",
                                    view: tools.getView(),
                                    key: this.key,
                                }
                            })
                            if (modal === true) {
                                this.componentUpdate()
                            }
                        })

                    }}>裁剪
                    </div>
                    <div class="btn" onClick={() => {
                        try {
                            let res = tools.xcall("get_list_val", this.key, 0, Number(this.page.total))
                            res = JSON.parse(res)
                            this.exportFile(res.list || "[]")
                        } catch (e) {

                        }
                    }}>导出
                    </div>
                </div>
            </div>
            <div class="table">
                <div class="tr">
                    <div class="th v v-index">index</div>
                    <div class="th k">内容</div>
                    <div class="th v v-a">操作</div>
                </div>
                <div class="list-tbody">
                    {
                        list.map((e, i) => {
                            let index = i + (this.page.current - 1) * this.page.size
                            return <div class="tr">

                                <div class="th v v-index">{index}</div>
                                <div class="th k">
                                    <div class="r-v">{e}</div>
                                    <div class="key-copy" onClick={() => this.doCopy(e)}>复制</div>
                                </div>
                                <div class="th v v-a">
                                    <div class="btn" onClick={() => {
                                        setTimeout(() => {
                                            let [x, y] = tools.windowPosition()
                                            let [w, h] = tools.windowSize()
                                            let modal = tools.getView().modal({
                                                width: 320,
                                                height: 200,
                                                x: x + w / 2 - 320 / 2,
                                                y: y + h / 2 - 200 / 2,
                                                url: "/redis/edit_redis_list_value.html",
                                                parameters: {
                                                    title: "修改list的值",
                                                    view: tools.getView(),
                                                    index,
                                                    key: this.key,
                                                    value: e
                                                }
                                            })
                                            if (modal === true) {
                                                this.componentUpdate()
                                            }
                                        })
                                    }}>修改
                                    </div>
                                    <div class="btn" onClick={() => {
                                        tools.confirm("确定要删除吗？")
                                            .then(res => {
                                                if (res === true) {
                                                    if (tools.xcall("delete_list_index_val", this.key, e) === true) {
                                                        return tools.alert("删除成功！")
                                                            .then(() => {
                                                                this.componentUpdate()
                                                            })
                                                    }
                                                    tools.alert("删除失败！")
                                                }
                                            })
                                    }}>删除
                                    </div>
                                </div>
                            </div>
                        })
                    }
                </div>
            </div>
            {this.renderPage(i => {
                this.page.current = i
                this.componentUpdate()
            })}
        </div>
    }

    setPage = ""

    renderPage(cb) {
        let max = 10
        let count = Math.ceil(this.page.total / this.page.size)
        let start = 1
        let end = 10
        let rects = []
        // 最多渲染个数
        if (count <= max) {
            end = count
        } else {
            // 当总渲染个数减去当前页小于渲染个数时最大渲染数为count，开始值为count-max
            if (this.page.current + Math.ceil(max / 2) >= count) {
                start = count - max
                end = count
            } else {
                start = this.page.current > Math.floor(max / 2) ? this.page.current - Math.floor(max / 2) : 1
                end = start - 1 + max
            }
        }
        for (let i = start; i <= end; i++) {
            if (i === Number(this.page.current)) {
                rects.push(<div class="disable navigation-item">{i}</div>)
            } else {
                rects.push(<div class="navigation-item" onClick={() => cb(i)}>{i}</div>)
            }
        }
        return <div class="navigation">
            <div class="total">共{this.page.total}条</div>
            <div class="jump-to">
                <select value={"" + this.page.size} onChange={(evt, ele) => {
                    this.page.size = Number(ele.value)
                    this.componentUpdate()
                }}>
                    <option value="10">10条/页</option>
                    <option value="20">20条/页</option>
                    <option value="50">50条/页</option>
                    <option value="100">100条/页</option>
                </select>
            </div>
            {
                this.page.current > 1 && <div class="navigation-item" onClick={(evt) => {
                    evt.stopPropagation()
                    this.page.current = this.page.current - 1
                    this.componentUpdate()
                }}><i class="icon icon-arrow-left"></i></div>
            }
            {rects}
            {
                this.page.current < count && <div class="navigation-item" onClick={(evt) => {
                    evt.stopPropagation()
                    console.log(+1)
                    this.page.current = Number(this.page.current) + 1
                    this.componentUpdate()
                }}><i class="icon icon-arrow-right"></i></div>
            }
            <div class="jump-to">前往<input type="text" value={this.setPage}
                                          onChange={(evt, ele) => {
                                              if (!/^\d+$/g.test(ele.value)) {
                                                  return this.setPage = ""
                                              }
                                              if (ele.value > count) {
                                                  return this.setPage = ""
                                              }
                                              if (ele.value < 1) {
                                                  return this.setPage = ""
                                              }
                                              if (ele.value >= 1 && ele.value <= count) {
                                                  this.setPage = ele.value
                                              }
                                              this.page.current = this.setPage
                                              this.componentUpdate()
                                          }}/>页
            </div>
        </div>
    }
    setData = []
    renderSet() {
        tools.xcall("async_get_set_data", this.key, params => {
            //tools.log("async ->:", params)
            this.setData = params
            this.componentUpdate()
        })
        return <div class="list-info">
            <div class="list-info-title">
                <span><b>{this.key}</b>查询结果</span>
                <div class="list-info-title-action">
                    <div class="btn" onClick={() => {
                        setTimeout(() => {
                            let [x, y] = tools.windowPosition()
                            let [w, h] = tools.windowSize()
                            let modal = tools.getView().modal({
                                width: 320,
                                height: 200,
                                x: x + w / 2 - 320 / 2,
                                y: y + h / 2 - 200 / 2,
                                url: "/redis/append_set_value.html",
                                parameters: {
                                    title: "插入新值",
                                    view: tools.getView(),
                                    key: this.key,
                                }
                            })
                            if (modal === true) {
                                this.componentUpdate()
                            }
                        })

                    }}>新增
                    </div>
                    <div class="btn" onClick={() => {
                        this.exportFile(JSON.stringify(this.setData))
                    }}>导出
                    </div>
                </div>
            </div>
            <div class="table">
                <div class="tr">
                    <div class="th v v-index">#</div>
                    <div class="th k">值</div>
                    <div class="th v v-a v-s-a">操作</div>
                </div>
                <div class="list-tbody set-body">
                    {
                        this.setData.map((e, i) => {
                            return <div class="tr">

                                <div class="th v v-index">{i}</div>
                                <div class="th k">
                                    <div class="r-v">{e}</div>
                                    <div class="key-copy" onClick={() => this.doCopy(e)}>复制</div>
                                </div>
                                <div class="th v v-a v-s-a">
                                    <div class="btn" onClick={() => {
                                        tools.confirm("确定要删除吗？")
                                            .then(res => {
                                                if (res === true) {
                                                    if (tools.xcall("delete_set_val", this.key, e) === true) {
                                                        return tools.alert("删除成功！")
                                                            .then(() => {
                                                                this.componentUpdate()
                                                            })
                                                    }
                                                    tools.alert("删除失败！")
                                                }
                                            })
                                    }}>删除
                                    </div>
                                </div>
                            </div>
                        })
                    }
                </div>
            </div>
        </div>
    }

    renderHash() {
        let list = tools.xcall("get_hash_data", this.key)
        return <div class="list-info">
            <div class="list-info-title">
                <span><b>{this.key}</b>查询结果</span>
                <div class="list-info-title-action">
                    <div class="btn" onClick={() => {
                        setTimeout(() => {
                            let [x, y] = tools.windowPosition()
                            let [w, h] = tools.windowSize()
                            let modal = tools.getView().modal({
                                width: 320,
                                height: 240,
                                x: x + w / 2 - 320 / 2,
                                y: y + h / 2 - 240 / 2,
                                url: "/redis/append_hash_exist_key_value.html",
                                parameters: {
                                    title: "插入新值",
                                    view: tools.getView(),
                                    key: this.key,
                                }
                            })
                            if (modal === true) {
                                this.componentUpdate()
                            }
                        })

                    }}>新增
                    </div>
                    <div class="btn" onClick={() => {
                        this.exportFile(JSON.stringify(list))
                    }}>导出
                    </div>
                </div>
            </div>
            <div class="table">
                <div class="tr">
                    <div class="th v v-index">字段</div>
                    <div class="th k">值</div>
                    <div class="th v v-a">操作</div>
                </div>
                <div class="list-tbody hash-body">
                    {
                        list.map((e, i) => {
                            let index = i + (this.page.current - 1) * this.page.size
                            return <div class="tr">

                                <div class="th v v-index">{e.key}</div>
                                <div class="th k">
                                    <div class="r-v">{e.value}</div>

                                    <div class="key-copy" onClick={() => this.doCopy(e.value)}>复制</div>
                                </div>
                                <div class="th v v-a">
                                    <div class="btn" onClick={() => {
                                        setTimeout(() => {
                                            let [x, y] = tools.windowPosition()
                                            let [w, h] = tools.windowSize()
                                            let modal = tools.getView().modal({
                                                width: 320,
                                                height: 200,
                                                x: x + w / 2 - 320 / 2,
                                                y: y + h / 2 - 200 / 2,
                                                url: "/redis/edit_redis_hash_value.html",
                                                parameters: {
                                                    title: "修改hash的值",
                                                    view: tools.getView(),
                                                    index,
                                                    key: this.key,
                                                    field: e.key,
                                                    value: e.value
                                                }
                                            })
                                            if (modal === true) {
                                                this.componentUpdate()
                                            }
                                        })
                                    }}>修改
                                    </div>
                                    <div class="btn" onClick={() => {
                                        tools.confirm("确定要删除吗？")
                                            .then(res => {
                                                if (res === true) {
                                                    if (tools.xcall("delete_list_index_val", this.key, e) === true) {
                                                        return tools.alert("删除成功！")
                                                            .then(() => {
                                                                this.componentUpdate()
                                                            })
                                                    }
                                                    tools.alert("删除失败！")
                                                }
                                            })
                                    }}>删除
                                    </div>
                                </div>
                            </div>
                        })
                    }
                </div>
            </div>
        </div>
    }

    renderUnknown() {
        return <div class="key-result">
            <h1>Sorry {this.info[1]} not support yet.</h1>
        </div>
    }

    renderResult() {
        switch (this.info[0]) {
            case "string":
                return this.renderString()
            case "list":
                return this.renderList()
            case "set":
                return this.renderSet()
            case "hash":
                return this.renderHash()
            default:
                return this.renderUnknown()
        }
    }

    renderKeyInfo() {
        if (!this.key) {
            return <div class="key-detail-container-none">
                <span>Not choose a key</span>
            </div>
        }
        return <div class="key-detail-container">
            <div class="key-info">
                <div class="key-info-title">
                    Key基础信息
                </div>
                <div class="table">
                    <div class="tr">
                        <div class="th k">键</div>
                        <div class="th v">类型</div>
                        <div class="th v">大小</div>
                        <div class="th v v-t">TTL(毫秒)</div>
                    </div>
                    <div class="tr">
                        <div class="td k">{this.key}
                            <div class="key-copy" onClick={() => this.doCopy(this.key)}>复制</div>
                        </div>
                        <div class="td v">{this.info[0]}</div>
                        <div class="td v">{this.info[1]}</div>
                        <div class="td v v-t">{this.info[2]}</div>
                    </div>
                </div>
            </div>
            {this.renderResult()}
        </div>
    }

    render() {
        return <div class={"key-detail"}>
            <div class={"key-detail-actions"}>
                <button class="action-btn" onClick={() => this.addKey()}>
                    <i class="icon icon-plus"></i>
                    <span>新增</span>
                </button>
                <button class="action-btn" onClick={() => this.renameKey()}>
                    <i class="icon icon-pencil"></i>
                    <span>重命名</span>
                </button>
                <button class="action-btn" onClick={() => this.ttlKey()}>
                    <i class="icon icon-av-timer"></i>
                    <span>TTL</span>
                </button>
                <button class="action-btn" onClick={() => this.deleteKey()}>
                    <i class="icon icon-delete-forever"></i>
                    <span>删除</span>
                </button>
                <button class="action-btn" onClick={() => this.getKeyInfo()}>
                    <i class="icon icon-refresh"></i>
                    <span>刷新</span>
                </button>
            </div>
            {this.renderKeyInfo()}
        </div>
    }
}